namespace Weather;

public class NumberPixArryHelper
{
    private int _size;
    private int _rowCount;
    private Dictionary<int, Line> _lines;
    private Dictionary<char, int[]> _numberLines;
    public NumberPixArryHelper(Size size)
    {
        this._size = (int)size;
        this._rowCount = this._size * 2 - 1;
        this.InitLines();
        this.InitNumberLinesDict();        
    }

    public int RowCount => this._rowCount;
    public int Width => this._size;

    public int[,] GetNumberPixArry(char num)
    {
        int[,] pix = CreatEmptyArray(this._rowCount, this._size);
        int[] lines = _numberLines[num];
        for (int i = 0; i < lines.Length; i++)
        {
            var linKey = lines[i];
            var line = _lines[linKey];
            foreach (var pt in line.Points)
            {
                pix[pt.Y, pt.X] = 1;
            }
        }
        return pix;
    }

    public static int[,] CreatEmptyArray(int row, int col)
    {
        int[,] pix = new int[row, col];
        for (int i = 0; i < row; i++)
        {
            for (int j = 0; j < col; j++)
            {
                pix[i, j] = 0;
            }
        }
        return pix;
    }
    
    public static string[,] ConvertIntArryToStrArry(int[,] pix)
    {
        int rowCount = pix.GetLength(0);
        int colCount = pix.GetLength(1);
        string[,] arr = new string[rowCount,colCount];
    
        for (int r = 0; r < pix.GetLength(0); r++)
        {
            for (int c = 0; c < pix.GetLength(1); c++)
            {
                if(pix[r, c] > 0)
                    arr[r, c] = "██";
                else
                    arr[r, c] = "  ";
            }
        }

        return arr;
    }
    
    private void InitLines()
    {
        int A = 0;
        int B = this._size -1;
        int C = this._rowCount-1;
        _lines = new Dictionary<int, Line>()
        {
            {0, new Line(this._size).Init(false, A,A)},
            {1, new Line(this._size).Init(true,  A,A)},
            {2, new Line(this._size).Init(true,  B,A)},
            {3, new Line(this._size).Init(false, B,A)},
            {4, new Line(this._size).Init(true,  A,B)},
            {5, new Line(this._size).Init(true,  B,B)},
            {6, new Line(this._size).Init(false, C,A)},
        };
    }
    private void InitNumberLinesDict()
    {
        this._numberLines = new Dictionary<char, int[]>()
        {
            {'0', new int[]{0,1,2,4,5,6}},
            {'1', new int[]{2,5}},
            {'2', new int[]{0,2,3,4,6}},
            {'3', new int[]{0,2,3,5,6}},
            {'4', new int[]{1,2,3,5}},
            {'5', new int[]{0,1,3,5,6}},
            {'6', new int[]{0,1,3,4,5,6}},
            {'7', new int[]{0,2,5}},
            {'8', new int[]{0,1,2,3,4,5,6}},
            {'9', new int[]{0,1,2,3,5,6}},
        };
    }
    private class Line
    {
        public Line(int size)
        {
            this.Size = size;
            this.Points = new Point[size];
        }
        public Line Init(bool sasmeX, int same, int start)
        {
            var pts = GetPoints(start);
            for (int i = 0; i < this.Size; i++)
            {
                this.Points[i] = sasmeX ? new Point(same, pts[i]) : new Point(pts[i], same);
            }
            return this;
        }
        private int[] GetPoints(int start)
        { 
            int[] pts = new int[this.Size];
            for (int i = 0; i < this.Size; i++) 
            {
                pts[i] = start++;
            }
            return pts;
        }
        public Point[] Points { get; }
        public int Size { get; }
    }
    private struct Point
    {
        public Point(int x, int y)
        {
            this.X = x;
            this.Y = y;
        }
        public int X { get; }
        public int Y { get; }
    }
    public enum Size
    {
        Small = 3,
        Medium = 4,
    }
}